package org.snail.attendence.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.log4j.Log4j;
import org.apache.log4j.Logger;
import org.snail.attendence.bean.*;
import org.snail.attendence.cache.AttendenceCacheService;
import org.snail.attendence.mapper.AttendenceMapper;
import org.snail.attendence.service.AttendanceListService;
import org.snail.attendence.service.manager.AttendanceInfoManager;
import org.snail.base.AttendenceCondition;
import org.snail.common.DateUtils;
import org.snail.common.ExcelUtils;
import org.snail.constant.AttendenceConstant;
import org.snail.constant.ErrCodeConstant;
import org.snail.constant.WorkSheetConstant;
import org.snail.department.service.impl.DepartmentServiceImpl;
import org.snail.department.service.impl.DepartmentTreeNodeService;
import org.snail.employee.bean.EmployeesDO;
import org.snail.employee.service.impl.EmployeesServiceImpl;
import org.snail.exception.CommonException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Log4j
public class AttendanceListServiceImpl implements AttendanceListService {
    private static final Logger logger = Logger.getLogger(AttendanceListServiceImpl.class);

    @Autowired
    private AttendenceMapper attendenceMapper;
    @Autowired
    private EmployeesServiceImpl employeesService;
    @Autowired
    private DepartmentTreeNodeService departmentTreeNodeService;
    @Autowired
    private AttendanceInfoManager attendanceInfoManager;
    @Autowired
    private AttendenceCacheService attendenceCacheService;
    @Autowired
    private WxLeaveServiceImpl wxLeaveService;


    /**
     * 核算考勤业务逻辑
     *
     * @param attendanceCondition
     * @return
     * @throws ParseException
     */
    public List<AttendanceCheckDO> findAttendanceCheckBySearch(AttendanceCondition attendanceCondition) throws ParseException {
        // 结果数据
        List<AttendanceCheckDO> resultAttendanceCheckList = new ArrayList<>();
        List<AttendanceCheckDO> attendanceList = findAttendanceCheck(attendanceCondition);
        //设置部门
        dept(attendanceList, resultAttendanceCheckList);

        List<AttendanceCheckDO> finalAttendanceList = new ArrayList<>();
        if (attendanceCondition.getDeptId() != null && attendanceCondition.getDeptId() != 0L) {
            //核算考勤有部门 传递过来逻辑
            deptCondition(attendanceCondition, resultAttendanceCheckList, finalAttendanceList);

            return finalAttendanceList;
        }
        return resultAttendanceCheckList;
    }

    /**
     * 核算考勤有部门 传递过来逻辑
     * 从resultAttendanceCheckList 过滤一部分数据
     * 核算考勤
     *
     * @param attendanceCondition       条件参数对象
     * @param resultAttendanceCheckList 所有的核算考勤列表
     * @param finalAttendanceList       最后过滤之后的核算考勤列表
     */
    private void deptCondition(AttendanceCondition attendanceCondition, List<AttendanceCheckDO> resultAttendanceCheckList, List<AttendanceCheckDO> finalAttendanceList) {
        List<Integer> employeeIdList = new ArrayList<>();
        Map<Integer, List<EmployeesDO>> employeeByDeptMap = employeesService.getEmployeeByDeptMap(attendanceCondition.getDeptId());
        for (List<EmployeesDO> key : employeeByDeptMap.values()) {
            for (EmployeesDO employeesDO : key) {
                employeeIdList.add(employeesDO.getEmpId());
            }
        }
        for (AttendanceCheckDO attendanceCheckDO : resultAttendanceCheckList) {
            if (employeeIdList.contains(attendanceCheckDO.getEmpId())) {
                finalAttendanceList.add(attendanceCheckDO);
            }
        }
    }

    /**
     * 核算考勤设置部门
     *
     * @param attendanceList            所有核算信息但没有部门
     * @param resultAttendanceCheckList 设置好部门之后的所有核算信息
     */
    private void dept(List<AttendanceCheckDO> attendanceList, List<AttendanceCheckDO> resultAttendanceCheckList) {
        Map<Object, Object> deptEmpMap = departmentTreeNodeService.selectDeptByEmployeeId();
        for (AttendanceCheckDO attendanceCheckDO : attendanceList) {
            if (deptEmpMap.get(attendanceCheckDO.getEmpId()) != null) {
                attendanceCheckDO.setBelongsDept((String) deptEmpMap.get(attendanceCheckDO.getEmpId()));
                resultAttendanceCheckList.add(attendanceCheckDO);
            } else {
                attendanceCheckDO.setBelongsDept("");
                resultAttendanceCheckList.add(attendanceCheckDO);
            }
        }
    }


    /**
     * @param attendanceCondition
     * @return
     * @throws ParseException
     */
    public List<AttendanceCheckDO> findAttendanceCheck(AttendanceCondition attendanceCondition) throws ParseException {
        //最终返回的数据
        List<AttendanceCheckDO> resultAttendanceList = new ArrayList<>();
        List<Map<String, Object>> dates = attendenceMapper.findAttendanceDates(attendanceCondition);
        //<empId<月份<日期>>>
        //idDate 为了设置在岗周期JobPeriod
        Map<Integer, Map<Integer, List<Date>>> idDate = new HashMap<>();
        empMonth(dates, idDate);

        List<AttendanceCheckDO> attendanceCheckDOs = attendenceMapper.findAttendanceCheck(attendanceCondition);

        //设置在岗周期一个月就是一条数据
        //其中还设置了法定节假日
        jobPeriod(attendanceCheckDOs, resultAttendanceList, idDate);

        //设置微信请假时间
        setWxLeaveHour(resultAttendanceList);

        if (attendanceCondition.getEmpId() == null) {
            resultAttendanceList = repeatMonth(resultAttendanceList);
        }
        return resultAttendanceList;
    }

    /**
     * 处理微信请假数据
     * 设置微信请假时间
     *
     * @param attendanceCheckDOs
     */
    private void setWxLeaveHour(List<AttendanceCheckDO> attendanceCheckDOs) {
        WxleanveCondition wxleanveCondition = new WxleanveCondition();
        List<WxLeaveDO> wxLeaveDOs = wxLeaveService.findDetails(wxleanveCondition);
        //<empId,<leaveDate,realHour>>
        Map<Integer, Map<String, Double>> wxLeaveMap = new HashMap<Integer, Map<String, Double>>();
        initWxLeaveMap(wxLeaveDOs, wxLeaveMap);
        //设置微信请假时间
        initWxLeaveHour(attendanceCheckDOs, wxLeaveMap);


    }

    /**
     * 设置微信请假时间
     *
     * @param attendanceCheckDOs
     * @param wxLeaveMap
     */
    private void initWxLeaveHour(List<AttendanceCheckDO> attendanceCheckDOs, Map<Integer, Map<String, Double>> wxLeaveMap) {

        for (AttendanceCheckDO attendanceCheckDO : attendanceCheckDOs) {
            Integer empId = attendanceCheckDO.getEmpId();
            String attDateMonth = attendanceCheckDO.getAttendanceDateMonth();
            Map<String, Double> map = wxLeaveMap.get(empId);
            if (map != null) {
                for (Map.Entry entry : map.entrySet()) {
                    //k: "195-12-5"
                    String k = (String) entry.getKey();
                    if (k != null && k.contains(attDateMonth)) {
                        Double leaveHour = map.get(k);
                        attendanceCheckDO.addWxLeaveHour(leaveHour);
                    }
                }
            }
        }

    }

    /**
     * 处理微信考勤的数据格式
     * 方便核算考勤时取数据
     *
     * @param wxLeaveDOs
     * @param wxLeaveMap
     */
    private void initWxLeaveMap(List<WxLeaveDO> wxLeaveDOs, Map<Integer, Map<String, Double>> wxLeaveMap) {
        for (WxLeaveDO wxLeaveDO : wxLeaveDOs) {
            //员工主键id
            Integer empId = wxLeaveDO.getEmpId();
            //请假日期
            String leaveDate = wxLeaveDO.getLeaveDate();
            //请假时长
            Double realHour = Double.parseDouble(wxLeaveDO.getRealHour());
            if (empId != null) {
                if (wxLeaveMap.get(empId) == null) {
                    wxLeaveMap.put(empId, new HashMap<String, Double>());
                }
                Map<String, Double> leaveDateMap = wxLeaveMap.get(empId);
                leaveDateMap.put(leaveDate, realHour);
            }
        }
    }

    /**
     * 设置在岗周期 返回最终核算考勤
     *
     * @param attendanceCheckDOs
     * @param resultAttendanceList
     * @param idDate
     * @throws ParseException
     */
    private void jobPeriod(List<AttendanceCheckDO> attendanceCheckDOs, List<AttendanceCheckDO> resultAttendanceList, Map<Integer, Map<Integer, List<Date>>> idDate) throws ParseException {
        for (int i = 0; i < attendanceCheckDOs.size(); i++) {
            AttendanceCheckDO attendanceCheckDO = attendanceCheckDOs.get(i);
            if (attendanceCheckDO.getAttendanceDateMonth() != null) {
                Date attendanceCheckDODate = DateUtils.parseDate(attendanceCheckDO.getAttendanceDateMonth(), new SimpleDateFormat("yyyy-MM"));
                int attendanceCheckDOYear = attendanceCheckDODate.getYear();
                int attendanceCheckDOMonth = attendanceCheckDODate.getMonth();
                Map<Integer, List<Date>> dateMap = idDate.get(attendanceCheckDO.getEmpId());
                for (List<Date> dateList : dateMap.values()) {
                    int year = -1;
                    int month = -2;
                    List<Date> list = new ArrayList<>();
                    AttendanceCheckDO attendanceCheckDOCopy = new AttendanceCheckDO();
                    BeanUtils.copyProperties(attendanceCheckDO, attendanceCheckDOCopy);
                    list.add(dateList.get(0));
                    list.add(dateList.get(dateList.size() - 1));
                    //通过年月来获取当月工作日(其中包括法定节假日)
                    if (dateList.get(0) != null) {
                        year = dateList.get(0).getYear();
                        month = dateList.get(0).getMonth();
                        int legalWorkingDays = DateUtils.legalWorkingDay(dateList.get(0));
                        attendanceCheckDOCopy.setLegalWorkingDay(legalWorkingDays);
                    }
                    if (attendanceCheckDOYear == year && attendanceCheckDOMonth == month) {
                        attendanceCheckDOCopy.setJobPeriod(list);
                        resultAttendanceList.add(attendanceCheckDOCopy);
                    }
                }
            }

        }
    }

    /**
     * 查询考勤表生成<员工<月份<具体日期>>>
     *
     * @param dates
     * @param idDate
     */
    private void empMonth(List<Map<String, Object>> dates, Map<Integer, Map<Integer, List<Date>>> idDate) {
        for (int i = 0; i < dates.size(); i++) {
            Object empId = dates.get(i).get("empId");
            Object jobPeriod = dates.get(i).get("jobPeriod");
            if (jobPeriod != null) {
                Integer month = ((Date) jobPeriod).getMonth();
                if (idDate.get(empId) == null) {
                    idDate.put((Integer) empId, new HashMap<>());
                }
                if (idDate.get(empId).get(month) == null) {
                    idDate.get(empId).put(month, new ArrayList<>());
                }

                idDate.get(empId).get(month).add((Date) jobPeriod);
            }
        }
        //当月在岗日期排序
        for (Map<Integer, List<Date>> map : idDate.values()) {

            for (List<Date> dates1 : map.values()) {
                if (dates1 != null) {
                    dates1.sort(new Comparator<Date>() {
                        @Override
                        public int compare(Date o1, Date o2) {
                            int c = 0;
                            if (o1 != null && o2 != null) {
                                c = o1.compareTo(o2);
                            }
                            return c;
                        }
                    });
                }
            }

        }
    }

    /**
     * 核算考勤只显示最新一个月的数据
     *
     * @param resultAttendanceList
     * @return
     */
    private List<AttendanceCheckDO> repeatMonth(List<AttendanceCheckDO> resultAttendanceList) {
        //保留同一个人最近一个月的考勤信息
        Map<Integer, AttendanceCheckDO> attendanceCheckDOMap = new HashMap<>();
        for (AttendanceCheckDO attendanceCheckDO : resultAttendanceList) {
            Integer empId = attendanceCheckDO.getEmpId();
            if (attendanceCheckDOMap.get(empId) == null) {
                attendanceCheckDOMap.put(empId, attendanceCheckDO);
            } else {
                //从map里取出AttendanceCheckDO比较attendanceDateMonth将日期大的设置会Map里
                AttendanceCheckDO mapDO = attendanceCheckDOMap.get(empId);
                String listDateMonth = attendanceCheckDO.getAttendanceDateMonth();
                String mapDateMonth = mapDO.getAttendanceDateMonth();
                if (listDateMonth != null) {
                    if (listDateMonth.compareTo(mapDateMonth) > 0) {
                        attendanceCheckDOMap.put(empId, attendanceCheckDO);
                    }
                }
            }
        }
        List<AttendanceCheckDO> resList = new ArrayList<>(attendanceCheckDOMap.values());
        return resList;
    }

    /**
     * 核算考勤总计
     *
     * @param attendanceCondition
     * @return
     */
    public List<AttendanceCheckDO> findAttendanceCount(AttendanceCondition attendanceCondition) {
        List<AttendanceCheckDO> attendanceCheckDOs = attendenceMapper.findAttendanceCount(attendanceCondition);
        return attendanceCheckDOs;
    }

    /**
     * 核算考勤实现类
     *
     * @return
     */
    public List<AttendanceCheckDO> findAttendanceDetail(AttendanceCondition attendanceCondition) throws ParseException {
        List<AttendanceCheckDO> attendanceCheckDOs = attendenceMapper.findAttendanceDetail(attendanceCondition);
        for (AttendanceCheckDO attendanceCheckDO : attendanceCheckDOs) {
            String hours = getDuration(attendanceCheckDO);
            String state = getState(attendanceCheckDO);
            attendanceCheckDO.setDuration(hours);
            attendanceCheckDO.setState(state);
        }
        return attendanceCheckDOs;
    }


    /**
     * 保存考勤信息
     * 包含查询数据库做对比设置状态
     * 跟新考勤信息到数据库
     *
     * @param file
     * @param request
     */
    public void saveAttendance(CommonsMultipartFile file, HttpServletRequest request) throws Exception {
        List<AliWorkDTO>  aliWorkDTOs = prevAttendance(file, request);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    saveAttendenceQueue(aliWorkDTOs);
                } catch (Exception e) {
                    log.error("prevAttendance error:"+e.getMessage());
                }
            }
        }).start();


//        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
//        newCachedThreadPool.execute(new ThreadForpools(file,request));

    }
//    private class ThreadForpools implements Runnable{
//        private CommonsMultipartFile file;
//        private HttpServletRequest request;
//        public ThreadForpools(CommonsMultipartFile file,HttpServletRequest request){
//            this.file = file;
//            this.request = request;
//        }
//        @Override
//        public void run() {
//            try {
//                List<AliWorkDTO>  aliWorkDTOs = prevAttendance(file, request);
//                saveAttendenceQueue(aliWorkDTOs);
//            } catch (Exception e) {
//                log.error("prevAttendance error:"+e.getMessage());
//            }
//        }
//    }


    /**
     * 查询所有考勤的正常数据
     *
     * @return
     */
    public Map<String, Object> findAllNormal(AttendanceCondition attendanceCondition) {
        List<AliWorkDTO> aliWorkDTOs = null;
        Integer startPage = attendanceCondition.getStartPage();
        Integer pageSize = attendanceCondition.getPageSize();
        if (startPage != null && pageSize != null) {
            PageHelper.startPage(startPage, pageSize);
        }
        try {
            aliWorkDTOs = attendenceMapper.findAllNormal(attendanceCondition);
        } catch (Exception e) {
            log.error("查询正常考勤失败:" + e.getMessage());
        }
        PageInfo pageInfo = new PageInfo<>(aliWorkDTOs);
        //pageINfo封装了分页的详细信息，也可以指定连续显示的页数
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("pageInfo", pageInfo);
        return map;
    }

    /**
     * 查询所有
     *
     * @return
     */
    public Map<String, Object> findAllAbNormal(AttendanceCondition attendanceCondition) {
        List<AbnormalAttendanceDTO> abnormalAttendanceDTOs = null;
        Integer startPage = attendanceCondition.getStartPage();
        Integer pageSize = attendanceCondition.getPageSize();
        if (startPage != null && pageSize != null) {
            PageHelper.startPage(startPage, pageSize);
        }
        try {
            abnormalAttendanceDTOs = attendenceMapper.findAllAbNormal(attendanceCondition);
        } catch (Exception e) {
            log.error("查询异常考勤失败:" + e.getMessage());
        }
        PageInfo pageInfo = new PageInfo<>(abnormalAttendanceDTOs);
        //pageINfo封装了分页的详细信息，也可以指定连续显示的页数
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("pageInfo", pageInfo);
        return map;
    }

    /**
     * 考勤预览
     *
     * @param file
     * @param request
     */
    public synchronized List<AliWorkDTO>  prevAttendance(CommonsMultipartFile file, HttpServletRequest request) throws Exception {
        HttpSession session = request.getSession();
        ServletContext servletContext = session.getServletContext();
        String path = servletContext.getRealPath("upload");
        List<AliWorkDTO> attOriginList = ExcelUtils.getListFromExcel(file, path, AliWorkDTO.class, 4);
        compareDBAttendance(attOriginList);
        return attOriginList;
    }

    /**
     * public void saveAttendenceQueue(List<AliWorkDTO> aliWorkDTOs);
     * 通过队列保存考勤信息
     */
    public void saveAttendenceQueue(List<AliWorkDTO> aliWorkDTOs) {
        attendanceInfoManager.saveAttendance(aliWorkDTOs);
    }

    /**
     * 和数据库做对比做预览页面
     * 0:不变  1:新增  2: 修改
     */
    public void compareDBAttendance(List<AliWorkDTO> aliWorkDTOList) throws Exception {
        //从数据库查询考勤
        //<外包工号,<日期,<Bean>>
        Map<String, Map<Date, AttendenceCommonDO>> attMap = new HashMap<>();
        List<AttendenceCommonDO> attendenceCommonDOs = findAllAttendenceCommon();


        for (AttendenceCommonDO attendenceCommonDO : attendenceCommonDOs) {
            String aliNum = attendenceCommonDO.getAliNumber();
            Date d = attendenceCommonDO.getAttendanceDate();
            if (StringUtils.isEmpty(aliNum)) {
                log.error("数据库对比考勤时此员工没有外包工号:" + attendenceCommonDO);
            }
            if (!StringUtils.isEmpty(aliNum)) {
                if (attMap.get(aliNum) == null) {
                    attMap.put(aliNum, new HashMap<>());
                }
                attMap.get(aliNum).put(d, attendenceCommonDO);
            }
        }
        for (AliWorkDTO aliWorkDTO : aliWorkDTOList) {
            //将不再考勤组的人员过滤掉
            if (AttendenceConstant.NOT_IN_ATTENDENCE.equals(aliWorkDTO.getOrder())) {
                aliWorkDTO.setState(0);
                continue;
            }

            if (attendenceCommonDOs.size() == 0) {
                aliWorkDTO.setState(1);
            } else {
                String aliNumber = aliWorkDTO.getAliNumber();
                String dateStr = aliWorkDTO.getDateStr();
                if (StringUtils.isEmpty(dateStr)) {
                    throw new CommonException(ErrCodeConstant.ILLEGAL_PARAM, "保存考勤信息时考勤时间为空");
                } else {
                    Date attendanceDate = DateUtils.parseDate(dateStr.split(" ")[0], new SimpleDateFormat("yy-MM-dd"));
                    AttendenceCommonDO attendenceCommonDO = null;
                    Map dateMap = attMap.get(aliNumber);
                    if (dateMap != null) {
                        Object obj = dateMap.get(attendanceDate);
                        if (obj != null) {
                            attendenceCommonDO = (AttendenceCommonDO) obj;
                        }
                    }
                    if (attendenceCommonDO == null) {
                        aliWorkDTO.setState(1);
                        log.info("新增的考勤数据:" + aliWorkDTO);
                    } else if (!checkAttendenceDB(aliWorkDTO, attendenceCommonDO)) {
                        aliWorkDTO.setState(2);
                    } else {
                        aliWorkDTO.setState(0);
                    }
                }
            }
        }

    }







    /**
     * 从excel中以工号和考勤时间为条件 去数据库查找数据
     * 判断此数据和数据库中的数据其他字段是否一样
     * 做修改操作
     *
     * @param aliWorkDTO         excel表中的数据
     * @param attendenceCommonDO 数据库中的数据
     * @return boolean
     */
    private boolean checkAttendenceDB(AliWorkDTO aliWorkDTO, AttendenceCommonDO attendenceCommonDO) throws ParseException {
        AttendenceCountDO attendenceCountDO = attendenceMapper.findAttendenceCount(attendenceCommonDO);
        boolean result = true;
        if (!aliWorkDTO.getEmployeeName().equals(attendenceCommonDO.getEmployeeName())) {
            result = false;
        } else if (aliWorkDTO.getOrder() != null && !aliWorkDTO.getOrder().equals(attendenceCommonDO.getOrders())) {
            result = false;
        } else if (aliWorkDTO.getPunchTime1() != null && !aliWorkDTO.getPunchTime1().equals(attendenceCommonDO.getPunchTime1())) {
            result = false;
        } else if (aliWorkDTO.getPunchComment1() != null && !aliWorkDTO.getPunchComment1().equals(attendenceCommonDO.getPunchComment1())) {
            result = false;
        } else if (aliWorkDTO.getPunchTime2() != null && !aliWorkDTO.getPunchTime2().equals(attendenceCommonDO.getPunchTime2())) {
            result = false;
        } else if (aliWorkDTO.getPunchComment2() != null && !aliWorkDTO.getPunchComment2().equals(attendenceCommonDO.getPunchComment2())) {
            result = false;
        } else if (aliWorkDTO.getApproval() != null && !aliWorkDTO.getApproval().equals(attendenceCommonDO.getApproval())) {
            result = false;
        } else if (aliWorkDTO.getAttendanceDay() != null && Double.parseDouble(aliWorkDTO.getAttendanceDay()) != attendenceCountDO.getAttendanceDay()) {
            result = false;
        } else if (aliWorkDTO.getFreeDay() != null && !(comparStrDouble(aliWorkDTO.getFreeDay(), attendenceCountDO.getFreeDay()))) {
            result = false;
        } else if (aliWorkDTO.getAttendenceMin() != null && Integer.parseInt(aliWorkDTO.getAttendenceMin()) != attendenceCountDO.getAttendenceMin()) {
            result = false;
        } else if (aliWorkDTO.getTardinessCount() != null && Integer.parseInt(aliWorkDTO.getTardinessCount()) != attendenceCountDO.getTardinessCount()) {
            result = false;
        } else if (aliWorkDTO.getTardinessMin() != null && Integer.parseInt(aliWorkDTO.getTardinessMin()) != attendenceCountDO.getTardinessMin()) {
            result = false;
        } else if (aliWorkDTO.getCriticalTardinessCount() != null && Integer.parseInt(aliWorkDTO.getCriticalTardinessCount()) != attendenceCountDO.getCriticalTardinessCount()) {
            result = false;
        } else if (aliWorkDTO.getCriticalTardinessMin() != null && Integer.parseInt(aliWorkDTO.getCriticalTardinessMin()) != attendenceCountDO.getCriticalTardinessMin()) {
            result = false;
        } else if (aliWorkDTO.getAbsenteeismDay() != null && comparStrDouble(aliWorkDTO.getAbsenteeismDay(), attendenceCountDO.getAbsenteeismDay())) {
            result = false;
        } else if (aliWorkDTO.getLeaveCount() != null && Integer.parseInt(aliWorkDTO.getLeaveCount()) != attendenceCountDO.getLeaveCount()) {
            result = false;
        } else if (aliWorkDTO.getLeaveMin() != null && comparStrDouble(aliWorkDTO.getLeaveMin(), attendenceCountDO.getLeaveMin())) {
            result = false;
        } else if (aliWorkDTO.getMissingCount() != null && comparStrDouble(aliWorkDTO.getMissingCount(), attendenceCountDO.getMissingCount())) {
            result = false;
        } else if (aliWorkDTO.getMissingCount2() != null && comparStrDouble(aliWorkDTO.getMissingCount2(), attendenceCountDO.getMissingCount2())) {
            result = false;
        } else if (aliWorkDTO.getAbsenteeismDay() != null && comparStrDouble(aliWorkDTO.getAbsenteeismDay(), attendenceCountDO.getAbsenteeismDay())) {
            result = false;
        } else if (aliWorkDTO.getLeaveHour() != null && comparStrDouble(aliWorkDTO.getLeaveHour(), attendenceCountDO.getLeaveHour())) {
            result = false;
        } else if (aliWorkDTO.getOverHour() != null && comparStrDouble(aliWorkDTO.getOverHour(), attendenceCountDO.getOverHour())) {
            result = false;
        } else if (aliWorkDTO.getWeekdayOverHour() != null && comparStrDouble(aliWorkDTO.getWeekdayOverHour(), attendenceCountDO.getOverHour())) {
            result = false;
        } else if (aliWorkDTO.getWeekendOverHour() != null && comparStrDouble(aliWorkDTO.getWeekendOverHour(), attendenceCountDO.getWeekendOverHour())) {
            result = false;
        } else if (aliWorkDTO.getFestivalOverHour() != null && comparStrDouble(aliWorkDTO.getFestivalOverHour(), attendenceCountDO.getFestivalOverHour())) {
            result = false;
        }
        return result;
    }

    /**
     * 保存核算考勤
     * 只保存不可调休工作日，周末，法定节假日
     */
    public void saveAttendanceCheck(List<AttendanceCheckDO> attendanceCheckDOs) throws CommonException {
        for (AttendanceCheckDO attendanceCheckDO : attendanceCheckDOs) {
            AttendanceCondition attendanceCondition = new AttendanceCondition();
            List<AttendenceCommonDO> attendenceCommonDOs = findAllAttendenceCommon();
            for (AttendenceCommonDO attendenceCommonDO : attendenceCommonDOs) {
                Date startTime = attendanceCheckDO.getStartCountTime();
                Integer empId = attendanceCheckDO.getEmpId();

                Integer queryEmpId = attendenceCommonDO.getEmpId();
                Date queryDate = attendenceCommonDO.getAttendanceDate();
                if (empId.equals(queryEmpId) && compareYearMonth(startTime, queryDate)) {
                    String attendanceDateMonth = parseDateToYearMonth(startTime);
                    attendanceCheckDO.setAttendanceDateMonth(attendanceDateMonth);
                    Integer commId = attendenceMapper.findCommIdByEmpId(attendanceCheckDO);
                    attendanceCondition.setCommId(commId);
                    Integer countId = attendenceMapper.findCountIdByCommId(attendanceCondition);
                    attendanceCheckDO.setCountId(countId);
                    attendenceMapper.saveAttendanceDetail(attendanceCheckDO);
                    break;
                }
            }

        }
    }

    /**
     * 获取上下班打卡时长 返回字符串
     *
     * @param attendanceCheckDO
     * @return
     * @throws ParseException
     */
    private String getDuration(AttendanceCheckDO attendanceCheckDO) throws ParseException {
        String hours = "";
        String sPunch1 = attendanceCheckDO.getPunchTime1();
        String sPunch2 = attendanceCheckDO.getPunchTime2();
        if (sPunch1 != null && sPunch2 != null) {
            if (sPunch2.contains("次日")) {
                sPunch2 = sPunch2.replace("次日", "").trim();
                String[] sArr = sPunch2.split(":");
                if ("00".equals(sArr[0])) {
                    sPunch2 = "24:" + sArr[1];
                } else if ("01".equals(sArr[0])) {
                    sPunch2 = "25:" + sArr[1];
                } else if ("02".equals(sArr[0])) {
                    sPunch2 = "26:" + sArr[1];
                } else if ("03".equals(sArr[0])) {
                    sPunch2 = "27:" + sArr[1];
                } else if ("04".equals(sArr[0])) {
                    sPunch2 = "28:" + sArr[1];
                } else if ("05".equals(sArr[0])) {
                    sPunch2 = "29:" + sArr[1];
                } else if ("06".equals(sArr[0])) {
                    sPunch2 = "30:" + sArr[1];
                } else if ("07".equals(sArr[0])) {
                    sPunch2 = "31:" + sArr[1];
                }
            }
            Date punch1 = DateUtils.parseDate(sPunch1, new SimpleDateFormat("HH:mm"));
            Date punch2 = DateUtils.parseDate(sPunch2, new SimpleDateFormat("HH:mm"));
            long ms = punch2.getTime() - punch1.getTime();
            hours = DateUtils.msTransHours(ms);
        }

        return hours;
    }

    /**
     * 获取状态
     *
     * @return
     */
    private String getState(AttendanceCheckDO attendanceCheckDO) {
        String state = "";
        String sPunchComment1 = attendanceCheckDO.getPunchComment1();
        String sPunchComment2 = attendanceCheckDO.getPunchComment2();
        if (!StringUtils.isEmpty(attendanceCheckDO.getApproval())) {
            state = attendanceCheckDO.getApproval();
        } else if (WorkSheetConstant.ORDER_FREE_TYPE.equals(attendanceCheckDO.getOrders())) {
            state = WorkSheetConstant.ORDER_FREE_TYPE;
        } else {
            state = "上班: " + sPunchComment1 + "," + "下班: " + sPunchComment2;
        }

        return state;
    }

    private boolean compareYearMonth(Date d1, Date d2) {
        boolean b = false;
        int commYear = d1.getYear();
        int commMonth = d1.getMonth();
        String scommYear = commYear + "";
        scommYear = scommYear.substring(scommYear.length() - 2);
        int commYear2 = Integer.parseInt(scommYear);

        int attYear = d2.getYear();
        int attMonth = d2.getMonth();
        String sattYear = attYear + "";
        sattYear = sattYear.substring(sattYear.length() - 2);
        int attYear2 = Integer.parseInt(sattYear);
        if (commYear2 == attYear2 && commMonth == attMonth) {
            b = true;
        }

        return b;
    }

    private String parseDateToYearMonth(Date date) {
        String strDate = "";
        int commYear = date.getYear();
        int commMonth = date.getMonth() + 1;
        String scommMonth = commMonth > 9 ? commYear + "" : "0" + commMonth;
        String scommYear = commYear + "";
        scommYear = scommYear.substring(scommYear.length() - 2);
        strDate = "20" + scommYear + "-" + scommMonth;
        return strDate;


    }


    private List<AttendenceCommonDO> findAllAttendenceCommon() throws CommonException {
        List<AttendenceCommonDO> attendenceCommonDOs = attendenceCacheService.findAllAttendenceToRedis();
        if (attendenceCommonDOs.size() == 0) {
            attendenceCommonDOs = attendenceMapper.findAllAttendenceCommon();
            attendenceCacheService.saveOrUpdateAttendenceToRedis(attendenceCommonDOs);
        }
        return attendenceCommonDOs;
    }

    /**
     * 根据    attendenceCommonDO 来查找对应的attendenceCountDO
     *
     * @param attendenceCommonDO
     * @return
     */
    private List<AttendenceCountDO> findAttendenceCount(AttendenceCommonDO attendenceCommonDO) {
        return null;
    }


    public List<AttendenceCommonDO> exhibitionAttendanceByConditionSearch(AttendanceCondition attendanceCondition) {
        //有时间查询条件按照时间条件查 没有这查询最大时间查询
        if (attendanceCondition.getYmDate() == null) {
            String ymDateMax = searchLastMonth();
            attendanceCondition.setYmDate(ymDateMax);
        }
        PageInfo pageInfo = exhibitionAttendanceByCondition(attendanceCondition);
        List<AttendenceCommonDO> resultAttendenceCommonDOList = pageInfo.getList();
        List<Integer> employeeIdList = new ArrayList<>();
        if (attendanceCondition.getDeptId() != null) {
            Map<Integer, List<EmployeesDO>> employeeByDeptMap = employeesService.getEmployeeByDeptMap(attendanceCondition.getDeptId());
            for (Integer key : employeeByDeptMap.keySet()) {
                List<EmployeesDO> employeesDOS = employeeByDeptMap.get(key);
                for (EmployeesDO employeesDO : employeesDOS) {
                    employeeIdList.add(employeesDO.getEmpId());
                }
            }

            List<AttendenceCommonDO> finalAttendanceCommonDOList = new ArrayList<>();
            for (AttendenceCommonDO attendenceCommonDO : resultAttendenceCommonDOList) {
                if (employeeIdList.contains(attendenceCommonDO.getEmpId())) {
                    finalAttendanceCommonDOList.add(attendenceCommonDO);
                }
            }
            return finalAttendanceCommonDOList;
        }
        return resultAttendenceCommonDOList;
    }


    public List<AttendenceCommonDO> detailsLetter(AttendenceCondition attendenceCondition) {
        List<AttendenceCommonDO> attendenceCommonDOs = new ArrayList<>();
        attendenceCommonDOs = attendenceMapper.findAttendenceCommonByCondition(attendenceCondition);
        return attendenceCommonDOs;
    }

    /**
     * 查询最新一个月数据
     *
     * @param
     * @return
     */

    public String searchLastMonth() {
        String ymDateMax = attendenceMapper.searchLastMonth();
        return ymDateMax;
    }

    private PageInfo exhibitionAttendanceByCondition(AttendanceCondition attendanceCondition) {
        Integer startPage = attendanceCondition.getStartPage();
        Integer pageSize = attendanceCondition.getPageSize();
        if (startPage != null && pageSize != null) {
            PageHelper.startPage(startPage, pageSize);
        }
        List<AttendenceCommonDO> attendence = attendenceMapper.exhibitionAttendanceByCondition(attendanceCondition);
        PageInfo pageInfo = new PageInfo(attendence);
        return pageInfo;
    }

    private boolean comparStrDouble(String str, Double dou) {
        boolean result = false;
        if (!StringUtils.isEmpty(str)) {
            result = (Double.parseDouble(str) + "").equals(dou + "");
        }
        return result;
    }
}
